package com.study.demo.aop.demo1_2.operation;

import com.study.demo.aop.demo1_2.parser.LogAnnotationParser;
import com.study.demo.aop.demo1_2.parser.SpringLogAnnotationParser;
import org.springframework.cache.annotation.CacheAnnotationParser;
import org.springframework.cache.interceptor.AbstractFallbackCacheOperationSource;
import org.springframework.lang.Nullable;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 * @author: elvin
 * @time: 2019-10-16 14:57
 * @desc:
 **/
public class AnnotationLogOperationSource extends AbstractFallbackLogOperationSource implements Serializable {

    private final LogAnnotationParser annotationParser = new SpringLogAnnotationParser();

    @Override
    protected LogOperation findLogOperations(Method method) {
        /**
         * new LogOperationProvider() {
         *             @Override
         *             public Collection<LogOperation> getLogOperations(LogAnnotationParser parser) {
         *                 return parser.parseLogAnnotations(method);
         *             }
         *         }
         *
         *  parser -> parser.parseLogAnnotations(method) 是一个匿名实现类:        LogOperationProvider
         *  在这个匿名实现类中, 只有一个需要实现的方法: getLogOperations
         *  在 getLogOperations 方法中, 返回了 : parser.parseLogAnnotations(method);
         */
        return determineLogOperations(parser -> parser.parseLogAnnotations(method));
    }

    @Override
    protected LogOperation findLogOperations(Class<?> clazz) {
        return determineLogOperations(parser -> parser.parseLogAnnotations(clazz));
    }

    @Nullable
    protected LogOperation determineLogOperations(LogOperationProvider provider) {
        LogOperation annOps = provider.getLogOperations(annotationParser);
        if (annOps != null) {
            return annOps;
        }
        return null;
    }

    @FunctionalInterface
    protected interface LogOperationProvider {

        @Nullable
        LogOperation getLogOperations(LogAnnotationParser parser);
    }
}
